<template>
  <div class="Lines">
    <TransitionGroup
      appear
      enter-active-class="animated fadeIn"
      leave-active-class="animated fadeOut"
    >
      <div
        :style="{
          transform: `translate(${line.x}, ${line.y})`,
          width: line.width,
          height: line.height,
        }"
        v-show="nodeTreeStore.moving"
        v-for="line in centerLines"
        :key="line.key"
        class="line"
      >
        <span :style="line.labelStyle" class="line-label">{{ line.label }}</span>
      </div>
    </TransitionGroup>
    <TransitionGroup
      appear
      enter-active-class="animated fadeIn"
      leave-active-class="animated fadeOut"
    >
      <div
        v-for="(item, key) in adsorptionLines"
        :key="key"
        class="line"
        :style="{
          transform: `translate(${item.x}, ${item.y})`,
          width: item.width,
          height: item.height,
        }"
      >
        <span v-if="item.label" :style="item.label.style" class="line-label">{{
          item.label.text
        }}</span>
      </div>
    </TransitionGroup>
  </div>
</template>
<script>
import { defineComponent, computed, inject } from 'vue';
import { useNodeTreeStore } from 'src/stores/nodeTree';

export default defineComponent({
  name: 'LinesComponent',
  setup() {
    const nodeTreeStore = useNodeTreeStore();
    const pageWidth = inject('pageWidth');
    const pageHeight = inject('pageHeight');
    const activeNode = computed(() => {
      return (
        nodeTreeStore.activeNode || {
          layout: {
            x: 0,
            y: 0,
            width: 0,
            height: 0,
          },
        }
      );
      // return nodeTreeStore.treeMap[nodeTreeStore.activeNodeId] || { layout: {} };
    });
    const components = computed(() => {
      return Object.keys(nodeTreeStore.treeMap).map((key) => {
        return nodeTreeStore.treeMap[key];
      });
    });

    const centerLines = computed(() => {
      // console.log(activeNode.value);
      let ls = [
        // {
        //   show: nodeTreeStore.moving,
        //   x: activeNode.value.layout.x + activeNode.value.layout.width / 2 + 'px',
        //   y: 0,
        //   height: activeNode.value.layout.y + 'px',
        //   width: '1px',
        //   key: 'n',
        //   label: Math.round(activeNode.value.layout.y) + 'px',
        // },
        // {
        //   show: nodeTreeStore.moving,
        //   x: activeNode.value.layout.x + activeNode.value.layout.width / 2 + 'px',
        //   y: activeNode.value.layout.y + activeNode.value.layout.height + 'px',
        //   height:
        //     pageHeight.value - activeNode.value.layout.y - activeNode.value.layout.height + 'px',
        //   width: '1px',
        //   key: 's',
        //   label:
        //     Math.round(
        //       pageHeight.value - activeNode.value.layout.y - activeNode.value.layout.height,
        //     ) + 'px',
        // },
        // {
        //   show: nodeTreeStore.moving,
        //   x: 0,
        //   y: activeNode.value.layout.y + activeNode.value.layout.height / 2 + 'px',
        //   width: activeNode.value.layout.x + 'px',
        //   height: '1px',
        //   key: 'w',
        //   label: Math.round(activeNode.value.layout.x) + 'px',
        // },
        // {
        //   show: nodeTreeStore.moving,
        //   x: activeNode.value.layout.x + activeNode.value.layout.width + 'px',
        //   y: activeNode.value.layout.y + activeNode.value.layout.height / 2 + 'px',
        //   width: pageWidth.value - activeNode.value.layout.x - activeNode.value.layout.width + 'px',
        //   height: '1px',
        //   key: 'e',
        //   label:
        //     Math.round(
        //       pageWidth.value - (activeNode.value.layout.x + activeNode.value.layout.width),
        //     ) + 'px',
        // },
      ];
      let top = {
        show: nodeTreeStore.moving,
        x: activeNode.value.layout.x + activeNode.value.layout.width / 2 + 'px',
        y: 0,
        height: activeNode.value.layout.y + 'px',
        width: '1px',
        key: 'n',
        label: Math.round(activeNode.value.layout.y) + 'px',
        labelStyle: {
          position: 'absolute',
          top: 0,
        },
      };
      let bottom = {
        show: nodeTreeStore.moving,
        x: activeNode.value.layout.x + activeNode.value.layout.width / 2 + 'px',
        y: activeNode.value.layout.y + activeNode.value.layout.height + 'px',
        height:
          pageHeight.value - activeNode.value.layout.y - activeNode.value.layout.height + 'px',
        width: '1px',
        key: 's',
        label:
          Math.round(
            pageHeight.value - activeNode.value.layout.y - activeNode.value.layout.height,
          ) + 'px',
        labelStyle: {
          position: 'absolute',
          bottom: 0,
        },
      };
      let left = {
        show: nodeTreeStore.moving,
        x: 0,
        y: activeNode.value.layout.y + activeNode.value.layout.height / 2 + 'px',
        width: activeNode.value.layout.x + 'px',
        height: '1px',
        key: 'w',
        label: Math.round(activeNode.value.layout.x) + 'px',
        labelStyle: {
          position: 'absolute',
          left: 0,
        },
      };
      let right = {
        show: nodeTreeStore.moving,
        x: activeNode.value.layout.x + activeNode.value.layout.width + 'px',
        y: activeNode.value.layout.y + activeNode.value.layout.height / 2 + 'px',
        width: pageWidth.value - activeNode.value.layout.x - activeNode.value.layout.width + 'px',
        height: '1px',
        key: 'e',
        label:
          Math.round(
            pageWidth.value - (activeNode.value.layout.x + activeNode.value.layout.width),
          ) + 'px',
        labelStyle: {
          position: 'absolute',
          right: 0,
        },
      };
      // components.value.forEach((component) => {
      //   if (component.id === activeNode.value.id) return;
      //   if (component.parentId === activeNode.value.id) return;
      //   // const {x,y,height,width} =
      //   // top
      //   if (
      //     component.layout.x <= activeNode.value.layout.x &&
      //     activeNode.value.layout.x <= component.layout.x + component.layout.width &&
      //     activeNode.value.layout.x + activeNode.value.layout.width <=
      //       component.layout.x + component.layout.width &&
      //     activeNode.value.layout.y - component.layout.y > 0
      //   ) {
      //     top.label =
      //       Math.round(activeNode.value.layout.y - (component.layout.y + component.layout.height)) +
      //       'px';
      //     top.y = Math.round(component.layout.y + component.layout.height) + 'px';
      //     top.height =
      //       Math.round(activeNode.value.layout.y - (component.layout.y + component.layout.height)) +
      //       'px';
      //     // top.height = activeNode.value.layout.y - component.layout.y;
      //   }
      //   // bottom
      //   if (
      //     component.layout.y >= activeNode.value.layout.y &&
      //     component.layout.x >= activeNode.value.layout.x &&
      //     component.layout.x + component.layout.width <=
      //       activeNode.value.layout.x + activeNode.value.layout.width
      //   ) {
      //     bottom.label =
      //       Math.round(
      //         component.layout.y - (activeNode.value.layout.y + activeNode.value.layout.height),
      //       ) + 'px';
      //     bottom.y = activeNode.value.layout.y + activeNode.value.layout.height;
      //     bottom.height =
      //       Math.round(
      //         component.layout.y - (activeNode.value.layout.y + activeNode.value.layout.height),
      //       ) + 'px';
      //   }
      // });
      // 根据key ls数组进行去重
      ls.push(top, bottom, left, right);
      return ls;
    });

    const DIFF = 5;
    const SPACE = 10;
    // const createLine = (key, { x, y, height, width }, nodeLayout, label) => {
    //   return {
    //     key,
    //     x: `${x}px`,
    //     y: `${y}px`,
    //     width: `${width}px`,
    //     height: `${height}px`,
    //     nodeLayout,
    //     label: {
    //       text: `${label.text}px`,
    //       style: {
    //         position: 'absolute',
    //         ...label.style,
    //       },
    //     },
    //   };
    // };
    // const createLineMap = {
    //   'top-left': (activeLayout, nodeLayout) => {
    //     return createLine(
    //       'top-left',
    //       {
    //         y: activeLayout.y + 'px',
    //         x: nodeLayout.x + nodeLayout.width + 'px',
    //         height: '1px',
    //         width: activeLayout.x - (nodeLayout.x + nodeLayout.width) + 'px',
    //       },
    //       nodeLayout,
    //       {
    //         text: activeNode.value.layout.x - (x + width) + 'px',
    //         style: {
    //           position: 'absolute',
    //           right: 0,
    //         },
    //       },
    //     );
    //   },
    //   'top-rotate-left': (activeLayout, nodeLayout) => {
    //     return createLine(
    //       'top-rotate-left',
    //       {
    //         y: activeLayout.rotateY + 'px',
    //         x: nodeLayout.rotateX + nodeLayout.rotateWidth + 'px',
    //         height: '1px',
    //         width: activeLayout.x - (nodeLayout.x + nodeLayout.width) + 'px',
    //       },
    //       nodeLayout,
    //       {
    //         text: activeNode.value.layout.x - (x + width) + 'px',
    //       },
    //     );
    //   },
    //   'top-right': () => {},
    //   'bottom-left': () => {},
    //   'bottom-right': () => {},
    //   'left-top': () => {},
    //   'left-bottom': () => {},
    //   'right-top': () => {},
    //   'right-bottom': () => {},
    // };
    const adsorptionLines = computed(() => {
      if (!nodeTreeStore.moving) return {};
      let lines = [];
      components.value.forEach((component) => {
        if (
          component.id === activeNode.value.id ||
          component.parentId === activeNode.value.id ||
          component.type === 'group'
        )
          return;
        const { x, y, width, height } = component.layout;
        // top
        let topLeft = {
          y: activeNode.value.layout.y + 'px',
          x: x + width + 'px',
          componentLayout: { x, y, width, height },
          height: '1px',
          width: activeNode.value.layout.x - (x + width) + 'px',
          label: {
            text: activeNode.value.layout.x - (x + width) + 'px',
            style: {
              position: 'absolute',
              right: 0,
            },
          },
          key: 'top-left',
        };
        let topRight = {
          key: 'top-right',
          x: activeNode.value.layout.x + activeNode.value.layout.width + 'px',
          y: activeNode.value.layout.y + 'px',
          height: '1px',
          componentLayout: { x, y, width, height },
          width: x - (activeNode.value.layout.x + activeNode.value.layout.width) + 'px',
          label: {
            text: x - (activeNode.value.layout.x + activeNode.value.layout.width) + 'px',
            style: {
              position: 'absolute',
              left: 0,
            },
          },
        };
        if (Math.abs(y - activeNode.value.layout.y) < SPACE) {
          if (x + width < activeNode.value.layout.x) {
            lines.push(topLeft);
          } else if (x > activeNode.value.layout.x + activeNode.value.layout.width) {
            lines.push(topRight);
          }
          if (Math.abs(y - activeNode.value.layout.y) < DIFF) {
            activeNode.value.layout.y = y;
          }
        } else if (Math.abs(y + height - activeNode.value.layout.y) < SPACE) {
          if (x + width < activeNode.value.layout.x) {
            lines.push(topLeft);
          } else if (x > activeNode.value.layout.x + activeNode.value.layout.width) {
            lines.push(topRight);
          }
          if (Math.abs(y - activeNode.value.layout.y) < DIFF) {
            activeNode.value.layout.y = y;
          }
          if (Math.abs(y + height - activeNode.value.layout.y) < DIFF) {
            activeNode.value.layout.y = Math.round(y + height);
          }
        }
        // bottom;
        let bottomLeft = {
          y: activeNode.value.layout.y + activeNode.value.layout.height + 'px',
          x: x + width + 'px',
          componentLayout: { x, y, width, height },
          height: '1px',
          width: activeNode.value.layout.x - (x + width) + 'px',
          label: {
            text: activeNode.value.layout.x - (x + width) + 'px',
            style: {
              position: 'absolute',
              right: 0,
            },
          },
          key: 'bottom-left',
        };
        let bottomRight = {
          key: 'bottom-right',
          x: activeNode.value.layout.x + activeNode.value.layout.width + 'px',
          y: activeNode.value.layout.y + activeNode.value.layout.height + 'px',
          height: '1px',
          componentLayout: { x, y, width, height },
          width: x - (activeNode.value.layout.x + activeNode.value.layout.width) + 'px',
          label: {
            text: x - (activeNode.value.layout.x + activeNode.value.layout.width) + 'px',
            style: {
              position: 'absolute',
              left: 0,
            },
          },
        };
        if (
          Math.abs(y + height - activeNode.value.layout.y - activeNode.value.layout.height) < SPACE
        ) {
          if (x + width < activeNode.value.layout.x) {
            lines.push(bottomLeft);
          } else if (x > activeNode.value.layout.x + activeNode.value.layout.width) {
            lines.push(bottomRight);
          }
          if (
            Math.abs(y + height - activeNode.value.layout.y - activeNode.value.layout.height) < DIFF
          ) {
            activeNode.value.layout.y = Math.round(y + height - activeNode.value.layout.height);
          }
        } else if (
          Math.abs(y - (activeNode.value.layout.y + activeNode.value.layout.height)) < SPACE
        ) {
          if (x + width < activeNode.value.layout.x) {
            lines.push(bottomLeft);
          } else if (x > activeNode.value.layout.x + activeNode.value.layout.width) {
            lines.push(bottomRight);
          }
          if (Math.abs(y - (activeNode.value.layout.y + activeNode.value.layout.height)) < DIFF) {
            activeNode.value.layout.y = Math.round(y - activeNode.value.layout.height);
          }
        }
        // left
        let leftTop = {
          x: activeNode.value.layout.x + 'px',
          y: y + height + 'px',
          componentLayout: { x, y, width, height },
          height: activeNode.value.layout.y - (y + height) + 'px',
          width: '1px',
          label: {
            text: activeNode.value.layout.y - (y + height) + 'px',
            style: {
              position: 'absolute',
              bottom: 0,
              // transform: 'translateX(-100%) translateY(100%)',
            },
          },
          key: 'left-top',
        };
        let leftBottom = {
          x: activeNode.value.layout.x + 'px',
          y: activeNode.value.layout.y + activeNode.value.layout.height + 'px',
          componentLayout: { x, y, width, height },
          height: y - (activeNode.value.layout.y + activeNode.value.layout.height) + 'px',
          width: '1px',
          label: {
            text: y - (activeNode.value.layout.y + activeNode.value.layout.height) + 'px',
            style: {
              position: 'absolute',
              top: 0,
              // transform: 'translateX(-100%) translateY(100%)',
            },
          },
          key: 'left-bottom',
        };
        if (Math.abs(x - activeNode.value.layout.x) < SPACE) {
          if (y + height < activeNode.value.layout.y) {
            lines.push(leftTop);
          } else if (y > activeNode.value.layout.y + activeNode.value.layout.height) {
            lines.push(leftBottom);
          }
          if (Math.abs(x - activeNode.value.layout.x) < DIFF) {
            activeNode.value.layout.x = Math.round(x);
          }
        } else if (Math.abs(x + width - activeNode.value.layout.x) < SPACE) {
          if (y + height < activeNode.value.layout.y) {
            lines.push(leftTop);
          } else if (y > activeNode.value.layout.y + activeNode.value.layout.height) {
            lines.push(leftBottom);
          }
          if (Math.abs(x + width - activeNode.value.layout.x) < DIFF) {
            activeNode.value.layout.x = Math.round(x + width);
          }
        }
        // right
        let rightTop = {
          x: activeNode.value.layout.x + activeNode.value.layout.width + 'px',
          y: y + height + 'px',
          componentLayout: { x, y, width, height },
          height: activeNode.value.layout.y - (y + height) + 'px',
          width: '1px',
          label: {
            text: activeNode.value.layout.y - (y + height) + 'px',
            style: {
              position: 'absolute',
              bottom: 0,
            },
          },
          key: 'right-top',
        };
        let rightBottom = {
          x: activeNode.value.layout.x + activeNode.value.layout.width + 'px',
          y: activeNode.value.layout.y + activeNode.value.layout.height + 'px',
          componentLayout: { x, y, width, height },
          height: y - (activeNode.value.layout.y + activeNode.value.layout.height) + 'px',
          width: '1px',
          label: {
            text: y - (activeNode.value.layout.y + activeNode.value.layout.height) + 'px',
            style: {
              position: 'absolute',
              top: 0,
            },
          },
          key: 'right-bottom',
        };
        if (
          Math.abs(x + width - activeNode.value.layout.x - activeNode.value.layout.width) < SPACE
        ) {
          if (y + height < activeNode.value.layout.y) {
            lines.push(rightTop);
          } else if (y > activeNode.value.layout.y + activeNode.value.layout.height) {
            lines.push(rightBottom);
          }
          if (
            Math.abs(x + width - activeNode.value.layout.x - activeNode.value.layout.width) < DIFF
          ) {
            activeNode.value.layout.x = x + width - activeNode.value.layout.width;
          }
        } else if (
          Math.abs(activeNode.value.layout.x + activeNode.value.layout.width - x) < SPACE
        ) {
          if (y + height < activeNode.value.layout.y) {
            lines.push(rightTop);
          } else if (y > activeNode.value.layout.y + activeNode.value.layout.height) {
            lines.push(rightBottom);
          }
          if (Math.abs(activeNode.value.layout.x + activeNode.value.layout.width - x) < DIFF) {
            activeNode.value.layout.x = x - activeNode.value.layout.width;
          }
        }
      });
      const noRepeatLineMap = {
        'top-left': (pre, cur) => {
          if (pre.componentLayout.x < cur.componentLayout.x) {
            return cur;
          } else {
            return pre;
          }
        },
        'top-right': (pre, cur) => {
          if (pre.componentLayout.x > cur.componentLayout.x) {
            return cur;
          } else {
            return pre;
          }
        },
        'bottom-left': (pre, cur) => {
          if (pre.componentLayout.x < cur.componentLayout.x) {
            return cur;
          } else {
            return pre;
          }
        },
        'bottom-right': (pre, cur) => {
          if (pre.componentLayout.x > cur.componentLayout.x) {
            return cur;
          } else {
            return pre;
          }
        },
        'left-top': (pre, cur) => {
          if (pre.componentLayout.y < cur.componentLayout.y) {
            return cur;
          } else {
            return pre;
          }
        },
        'left-bottom': (pre, cur) => {
          if (pre.componentLayout.y > cur.componentLayout.y) {
            return cur;
          } else {
            return pre;
          }
        },
        'right-top': (pre, cur) => {
          if (pre.componentLayout.y < cur.componentLayout.y) {
            return cur;
          } else {
            return pre;
          }
        },
        'right-bottom': (pre, cur) => {
          if (pre.componentLayout.y > cur.componentLayout.y) {
            return cur;
          } else {
            return pre;
          }
        },
      };
      lines = lines.reduce((pre, cur) => {
        // return computedLines[cur.key](pre, cur);
        if (!pre[cur.key]) {
          pre[cur.key] = cur;
        } else {
          pre[cur.key] = noRepeatLineMap[cur.key](pre[cur.key], cur);
        }
        return pre;
      }, {});
      return lines;
    });
    return {
      centerLines,
      activeNode,
      nodeTreeStore,
      adsorptionLines,
    };
  },
});
</script>
<style scope lang="scss">
.Lines {
  position: absolute;
  top: 0;
  left: 0;
  .line {
    position: absolute;
    top: 0;
    left: 0;
    background-color: $primary;
    z-index: 999;
    .line-label {
      background-color: hsla(210, 88%, 44%, 0.8);
      backdrop-filter: blur(10px);
      border-radius: 8px;
      padding: 4px 8px;
      font-size: 12px;
      // color: $primary;
      color: #fff;
    }
  }
}
</style>
